home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-02-09 | 6.3 KB | 250 lines | [TEXT/MPCC] |
-
- /*
- * CPlusLib.cp - C++ Runtime Support Routines for Metrowerks C++ (PowerPC)
- *
- * Copyright © 1993 metrowerks inc. All Rights Reserved.
- *
- */
-
-
- #include <stdlib.h>
-
-
- /* private types */
-
- typedef void (*ConstructorDestructor)(void *, int);
-
- typedef struct DestructorChain {
- struct DestructorChain *next; /* pointer to next destructor chain element */
- ConstructorDestructor destructor; /* pointer to destructor function */
- void *object; /* pointer to memory location (0L: element is marker) */
- } DestructorChain;
-
- typedef struct PTMF {
- long this_delta; /* delta to this pointer */
- long vtbl_offset; /* offset in vtable (-1: not a virtual function) */
- union {
- void *func_addr; /* nonvirtual function address */
- long ventry_offset; /* offset of virtual function entry in vtable */
- } func_data;
- } PTMF;
-
-
- /* private data */
-
- static DestructorChain *__global_destructor_chain; /* chain of global objects that need destruction */
- static DestructorChain *__local_destructor_chain; /* chain of local objects that need destruction */
-
-
- /* prototypes */
-
- extern "C" {
-
- PTMF *__ptmf_cast(long offset, const PTMF *ptmfrom, PTMF *ptmto);
-
- void *__register_global_object(void *object, ConstructorDestructor destructor, DestructorChain *regmem);
- void *__register_local_object(void *object, ConstructorDestructor destructor, DestructorChain *regmem);
-
- void __destroy_local_objects(DestructorChain *lastregmem);
- void __destroy_local_chain(void);
- void __destroy_global_chain(void);
-
- void *__new_arr(ConstructorDestructor constructor, size_t objectsize, size_t nobjects);
- void __del_arr(void *memptr, ConstructorDestructor destructor);
- void __dc_arr(void *memptr, ConstructorDestructor constructordestructor, short objectsize, short nobjects);
-
- }
-
-
- /*
- * __ptmf_cast - copy/cast a pointer-to-member-function
- *
- */
-
- PTMF *__ptmf_cast(long offset, const PTMF *ptmfrom, PTMF *ptmto)
- {
- ptmto->this_delta = ptmfrom->this_delta+offset;
-
- if(ptmfrom->vtbl_offset >= 0L) { // virtual function pointer
- ptmto->vtbl_offset = ptmfrom->vtbl_offset + offset;
- ptmto->func_data.ventry_offset = ptmfrom->func_data.ventry_offset;
- }
- else { // nonvirtual function pointer
- ptmto->vtbl_offset = -1L;
- ptmto->func_data.func_addr = ptmfrom->func_data.func_addr;
- }
-
- return(ptmto);
- }
-
-
- /*
- * __register_global_object - register a global object for later destruction
- *
- * We add the object and its destructor to a chain of (global object,destructor) pairs.
- * The standard termination routine will traverse this list and destroy all objects
- * whenever/however an application terminates.
- *
- */
-
- void *__register_global_object(void *object, ConstructorDestructor destructor, DestructorChain *regmem)
- {
- regmem->next = __global_destructor_chain;
- regmem->destructor = destructor;
- regmem->object = object;
- __global_destructor_chain = regmem;
- return(object);
- }
-
-
- /*
- * __register_local_object - register a local object for later destruction
- *
- * We add the object and its destructor to a chain of (local object,destructor) pairs.
- * These local objects are destroyed at the end of a scope or as part of stack unwinding
- * when an exception is thrown.
- *
- */
-
- void *__register_local_object(void *object, ConstructorDestructor destructor, DestructorChain *regmem)
- {
- regmem->next = __local_destructor_chain;
- regmem->destructor = destructor;
- regmem->object = object;
- __local_destructor_chain = regmem;
- return(object);
- }
-
-
- /*
- * __destroy_local_objects - destroy some local objects
- *
- * Call the destructor for every object in the local object chain up to (and
- * including) 'lastregmem'.
- *
- */
-
- void __destroy_local_objects(DestructorChain *lastregmem)
- {
- DestructorChain *chain;
- void *object;
-
- while ((chain = __local_destructor_chain) != 0) {
- if ((object = chain->object) != 0)
- (*chain->destructor)(object, -1);
- __local_destructor_chain = chain->next;
- if (chain == lastregmem)
- break;
- }
- }
-
-
- /*
- * __destroy_local_chain - destroy all local objects
- *
- * Call the destructor for every object in the local object chain.
- *
- */
-
- void __destroy_local_chain(void)
- {
- DestructorChain *chain;
- void *object;
-
- while ((chain = __local_destructor_chain) != 0) {
- if ((object = chain->object) != 0)
- (*chain->destructor)(object, -1);
- __local_destructor_chain = chain->next;
- }
- }
-
-
- /*
- * __destroy_global_chain - destroy all global objects
- *
- * Call the destructor for every object in the global object chain.
- *
- */
-
- void __destroy_global_chain(void)
- {
- DestructorChain *chain;
- void *object;
-
- while ((chain = __global_destructor_chain) != 0) {
- if ((object = chain->object) != 0)
- (*chain->destructor)(object, -1);
- __global_destructor_chain = chain->next;
- }
- }
-
-
- /*
- * __new_arr - allocate and construct an array of objects
- *
- * We allocate space for an array of 'nobjects' elements of size 'objectsize', and
- * space to store 'nobjects' and 'objectsize' (for later deletion). Then we call
- * the given constructor for each object in the array.
- *
- */
-
- void *__new_arr(ConstructorDestructor constructor, size_t objectsize, size_t nobjects)
- {
- char *memptr, *p;
-
- if ((memptr = (char *) ::operator new(2*sizeof(size_t) + nobjects*objectsize)) != 0) {
- memptr += 2*sizeof(size_t);
- ((size_t *) memptr)[-2] = objectsize;
- ((size_t *) memptr)[-1] = nobjects;
- if (constructor) {
- for (p = memptr; nobjects--; p += objectsize)
- (*constructor)(p, 1);
- }
- }
-
- return(memptr);
- }
-
-
- /*
- * __del_arr - destroy and deallocate an array of objects
- *
- * We use the previously saved 'nobjects' and 'objectsize' values to call the
- * destructor for each element of the array. Then we delete the space allocated
- * to it.
- *
- */
-
- void __del_arr(void *memptr, ConstructorDestructor destructor)
- {
- size_t nobjects, objectsize;
- char *p;
-
- if (memptr) {
- if (destructor) {
- objectsize = ((size_t *) memptr)[-2];
- nobjects = ((size_t *) memptr)[-1];
- for (p = (char *) memptr; nobjects--; p += objectsize)
- (*destructor)(p, -1);
- }
- ::delete (&((size_t *) memptr)[-2]);
- }
- }
-
-
- /*
- * __dc_arr - construct or destroy a statically allocated array of objects
- *
- * We call the given constructor or destructor for each of 'nobjects' elements of size
- * 'objectsize' in a statically allocated array.
- *
- */
-
- void __dc_arr(void *memptr, ConstructorDestructor constructordestructor, short objectsize, short nobjects)
- {
- char *p;
-
- for (p = (char *) memptr; nobjects--; p += objectsize)
- (*constructordestructor)(p, -1);
- }
-